package org.ljp2010.bot.sinaweibo1;

import java.io.*;
import java.net.*;
import java.util.*;

public class WapEmu {
	private String Referer = "";
	private String CurAction = "GET";
	public String Path = "";
	public String tHost = "";

	public String CookieStoneSite[] = { "sina.cn", "weibo.cn", "sina.com.cn" };
	private String Cookies[] = { "", "", "" };

	private static String BOUNDARYSTR = "-----------------------------3873432373413";
	private static byte[] BOUNDARY = null;
	private static String UA = "NOKIA6120c";

	private int retrytimes = 3;
	private int curtimes = 0;

	public void WapEmu() {
		try {
			BOUNDARY = BOUNDARYSTR.getBytes("utf-8");
		} catch (Exception e) {

		}
	}

	public static String replace(String strSource, String strFrom, String strTo) {
		if (strSource == null) {
			return null;
		}
		int i = 0;
		if ((i = strSource.indexOf(strFrom, i)) >= 0) {
			char[] cSrc = strSource.toCharArray();
			char[] cTo = strTo.toCharArray();
			int len = strFrom.length();
			StringBuffer buf = new StringBuffer(cSrc.length);
			buf.append(cSrc, 0, i).append(cTo);
			i += len;
			int j = i;
			while ((i = strSource.indexOf(strFrom, i)) > 0) {
				buf.append(cSrc, j, i - j).append(cTo);
				i += len;
				j = i;
			}
			buf.append(cSrc, j, cSrc.length - j);
			return buf.toString();
		}
		return strSource;
	}

	public static String[] array_unique(String[] a, String[] b) {
		// array_unique
		List<String> list = new LinkedList<String>();
		for (int i = 0; i < a.length; i++) {
			if (!list.contains(a[i])) {
				list.add(a[i]);
			}
		}
		for (int i = 0; i < b.length; i++) {
			if (!list.contains(b[i])) {
				list.add(b[i]);
			}
		}
		return (String[]) list.toArray(new String[list.size()]);
	}

	public String AddCookie(String cookie, String add) {
		String cs[] = cookie.split(";");
		String as[] = add.split(";");

		for (int i = 0; i < as.length; i++) {
			as[i] = as[i].trim();
		}
		for (int i = 0; i < cs.length; i++) {
			cs[i] = cs[i].trim();
		}
		String alls[] = array_unique(cs, as);
		StringBuffer ret = new StringBuffer();
		for (int i = 0; i < alls.length; i++) {
			if (alls[i] != null && !alls[i].equals("")) {
				if (alls[i].startsWith("path") || alls[i].startsWith("domain")
						|| alls[i].startsWith("expires")) {
					continue;
				}
				ret.append(alls[i] + "; ");
			}
		}
		return ret.toString();
	}

	public String Byte2String(byte b[]) {
		String ret = "";
		try {
			ret = new String(b, "utf-8");
		} catch (Exception e) {
		}
		return ret;
	}

	public byte[] String2Byte(String s) {
		byte ret[] = null;
		try {
			ret = s.getBytes("utf-8");
		} catch (Exception e) {
		}
		return ret;
	}

	public byte[] Get(String url) {
		return Get(url, new String[0]);
	}

	// quarys = {name,xxx,age,12,...};
	public byte[] Get(String url, String quarys[]) {
		url = url + "?";
		for (int i = 0; i < quarys.length / 2; i++) {
			url = url + quarys[i * 2] + "=" + quarys[i * 2 + 1] + "&";
		}
		url = url.substring(0, url.length() - 1);

		CurAction = "GET";
		curtimes = 0;
		return Send(url, new String[0], new byte[0]);
	}

	// quarys = {name,xxx,age,12,...};
	public byte[] Post(String url, String quarys[]) {
		String postdata = "";
		for (int i = 0; i < quarys.length / 2; i++) {
			postdata = postdata + quarys[i * 2] + "=" + quarys[i * 2 + 1] + "&";
		}
		postdata = postdata.substring(0, postdata.length() - 1);
		byte bpost[] = new byte[0];
		try {
			bpost = postdata.getBytes("utf-8");
		} catch (Exception e) {
			System.out.println("Error encoding post data to utf-8 format, "
					+ "post data will not send to host.");
		}
		CurAction = "POST";
		curtimes = 0;
		return Send(url, new String[0], bpost);
	}

	// parts = {parthead1,partdata1,parthead1,partdata1,...};
	public byte[] PostMultiPart(String url, MultiPartData parts[]) {
		int l = 0;
		int bl = BOUNDARY.length;
		for (int i = 0; i < parts.length; i++) {
			l = l + bl + 2 // "\r\n"
					+ parts[i].GetSize();
		}
		l = l + bl + 4; // "--\r\n"
		byte bpost[] = new byte[l];
		int p = 0;

		for (int i = 0; i < parts.length; i++) {
			System.arraycopy(BOUNDARY, 0, bpost, p, BOUNDARY.length);
			p = p + BOUNDARY.length;
			bpost[p++] = '\r';
			bpost[p++] = '\n';
			System.arraycopy(parts[i].GetData(), 0, bpost, p,
					parts[i].GetSize());
			p = p + parts[i].GetSize();
		}
		System.arraycopy(BOUNDARY, 0, bpost, p, BOUNDARY.length);
		p = p + BOUNDARY.length;
		bpost[p++] = '-';
		bpost[p++] = '-';
		bpost[p++] = '\r';
		bpost[p++] = '\n';

		CurAction = "POST";
		String addpa[] = { "Content-Type",
				"multipart/form-data; boundary=" + BOUNDARYSTR };
		curtimes = 0;
		return Send(url, addpa, bpost);
	}

	public byte[] Send(String url, String headpa[], byte data[]) {
		HttpURLConnection con = null;
		URL u = null;
		byte ret[] = null;

		try {
			if (url.startsWith("http://") == false) {
				if (url.startsWith(tHost) == true)
					url = "http://" + url; // http:// +
											// weibo.com/eee/xxx/hhh.php
				else if (url.startsWith("/") == true)
					url = "http://" + tHost + url; // http:// + weibo.com +
													// /index.html
				else if (Path.endsWith("/") == true)
					url = "http://" + Path + url; // http:// + weibo.com/xxx/ +
													// a.html
				else
					url = "http://" + Path + "/" + url; // http:// weibo.com + /
														// + xxx.php
			}

			url = replace(url, "&amp;", "&");

			u = new URL(url);
			con = (HttpURLConnection) u.openConnection();

			con.setInstanceFollowRedirects(false);
			con.setRequestMethod(CurAction);
			con.setDoInput(true);
			con.setDoOutput(true);

			con.setRequestProperty("User-Agent", UA);
			if (Referer != null && !Referer.equals(""))
				con.setRequestProperty("Referer", Referer);

			for (int i = 0; i < CookieStoneSite.length; i++) {
				if (CookieStoneSite[i].equals(con.getURL().getHost()))
					if (Cookies[i] != null && !Cookies[i].equals("")) {
						String c = Cookies[i];
						c = c.substring(0, c.length() - 2);
						con.setRequestProperty("Cookie", c);
					}
			}

			// con.setRequestProperty("Accept",
			// "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			// con.setRequestProperty("Accept-Language", "zh-cn,zh;q=0.5");
			// con.setRequestProperty("Accept-Encoding", "deflate");
			// con.setRequestProperty("Accept-Charset",
			// "GB2312,utf-8;q=0.7,*;q=0.7");

			for (int i = 0; i < headpa.length / 2; i++) {
				con.setRequestProperty(headpa[i * 2], headpa[i * 2 + 1]);
			}

			if (CurAction.equals("POST")) {
				// con.setFixedLengthStreamingMode(data.length);
				// con.setChunkedStreamingMode(data.length);
				DataOutputStream out = new DataOutputStream(
						con.getOutputStream());
				out.write(data);
				out.flush();
			}

			int code = con.getResponseCode();

			if (con.getHeaderField("Set-Cookie") != null) {
				for (int i = 0; i < CookieStoneSite.length; i++) {
					if (con.getURL().getHost().endsWith(CookieStoneSite[i]))
						Cookies[i] = AddCookie(Cookies[i],
								con.getHeaderField("Set-Cookie"));
				}
			}
			String tmpcookie = con.getHeaderField("Set-Cookie");
			String tmphost = con.getURL().getHost();

			Referer = con.getURL().toString();
			tHost = con.getURL().getHost();
			String tPath = con.getURL().getPath();
			Path = tHost + tPath.substring(0, tPath.lastIndexOf("/") + 1);

			if (con.getResponseCode() >= 300 && con.getResponseCode() < 400) {
				String loc = con.getHeaderField("Location");
				if (loc.startsWith("/")) {
					loc = con.getURL().getHost() + loc;
				}
				System.out.println("page replaced " + loc);
				ret = Send(loc, headpa, data);
			} else {
				String length = con.getHeaderField("Content-Length");

				DataInputStream dis = new DataInputStream(con.getInputStream());
				byte b[] = null;
				if (length != null && new Integer(length) > 0) {
					int l = new Integer(length);

					b = new byte[l];
					int bpoint = 0;
					int ka;

					while (bpoint != l) {
						int len = dis.read(b, bpoint, l - bpoint);
						bpoint = bpoint + len;
					}
					if (bpoint != l) {
						throw new IOException();
					}
				} else {
					// StringBuffer sb = new StringBuffer();

					b = new byte[1024 * 1024];
					int bpoint = 0;
					int ka;

					while ((ka = dis.read(b, bpoint, 1024 * 1024 - bpoint)) != -1) {
						bpoint = bpoint + ka;
					}
					// System.out.print("" + bpoint + ":" + ka);
				}

				String logstr = Byte2String(b);
				ret = b;
			}
		} catch (Exception e) {
			System.out.print(e.toString());
			e.printStackTrace();
			con.disconnect();
			if (curtimes++ != retrytimes)
				return Send(url, headpa, data);
		}
		con.disconnect();

		return ret;
	}
}
